package io.kiki.sba.registry.server.clientInterface.wrapper;

import io.kiki.sba.registry.common.model.constants.ValueConstants;
import io.kiki.sba.registry.common.model.store.BaseInfo;
import io.kiki.sba.registry.common.model.store.StoreData.DataType;
import io.kiki.sba.registry.common.model.store.Subscriber;
import io.kiki.sba.registry.common.model.wrapper.WrapperInterceptor;
import io.kiki.sba.registry.common.model.wrapper.WrapperInvocation;
import io.kiki.sba.registry.server.clientInterface.filter.ProcessFilter;
import io.kiki.sba.registry.server.clientInterface.push.FirePushService;
import io.kiki.sba.registry.server.clientInterface.registry.ClientInterfaceRegistry;
import io.kiki.sba.registry.server.shared.remoting.RemotingHelper;
import org.apache.logging.log4j.util.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;


public class BlacklistWrapperInterceptor implements WrapperInterceptor<RegisterInvokeData, Boolean> {
    private static final Logger logger = LoggerFactory.getLogger(BlacklistWrapperInterceptor.class);
    @Autowired
    protected ClientInterfaceRegistry clientInterfaceRegistry;

    @Autowired
    protected FirePushService firePushService;
    /**
     * blacklist filter
     */
    @Autowired
    protected ProcessFilter<BaseInfo> processFilter;

    @Override
    public Boolean invokeCodeWrapper(WrapperInvocation<RegisterInvokeData, Boolean> wrapperInvocation) throws Exception {

        RegisterInvokeData registerInvokeData = wrapperInvocation.getParameterSupplier().get();
        BaseInfo storeData = (BaseInfo) registerInvokeData.getStoreData();
        if (Strings.isNotBlank(storeData.attributeOf(ValueConstants.BLOCKED_REQUEST_KEY)) || processFilter.match(storeData)) {
            if (DataType.publisher == storeData.getDataType()) {
                // match blacklist stop pub.
                logger.info("[pub],{},{}", storeData.getDataInfoId(), RemotingHelper.getAddressString(storeData.getClientUrl()));
                return true;
            }

            if (DataType.subscriber == storeData.getDataType()) {
                // in some case, need to push empty to new subscriber, and stop sub
                // else, filter not stop sub
                if (clientInterfaceRegistry.isPushEmpty((Subscriber) storeData)) {
                    firePushService.fireOnPushEmpty((Subscriber) storeData, clientInterfaceRegistry.getDataCenterWhenPushEmpty());
                    logger.info("[sub],{},{}", storeData.getDataInfoId(), RemotingHelper.getAddressString(storeData.getClientUrl()));
                    return true;
                }
            }
        }
        return wrapperInvocation.proceed();
    }

    @Override
    public int getOrder() {
        return 200;
    }
}
